fastlane_require 'yaml'
fastlane_require 'plist'

before_all do
  ENV["FASTLANE_EXPLICIT_OPEN_SIMULATOR"] = "2"
end

desc "Runs all the tests"
lane :test do
  devices = ['iPhone 11 Pro']
  os_version = '13.3'
  
  Dir.mktmpdir do |tmp_dir|
    xcodebuild({
      workspace: "PhotoStickers.xcworkspace",
      scheme: "MessagesExtension",
      configuration: "Prefilled",
      derivedDataPath: tmp_dir,
      xcargs: "-sdk iphonesimulator -destination 'generic/platform=iOS Simulator' CODE_SIGN_IDENTITY='' CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=NO"
    })
    app_path = sh("find #{tmp_dir} -name *.app -type d").strip()
    
    prepare_simulators(devices, os_version, app_path, 'en_US')

    scan({
      devices: devices,
    })
  end
end

desc "Submit a new Beta Build to Apple TestFlight"
lane :beta do |options|
  
  version = options[:version]
  increment_version_number version_number: version unless version.nil? || version.scan(/\d+\.\d+\.\d+/).length == 0
  increment_build_number

  sync_code_signing

  build_ios_app

  upload_to_app_store({
    skip_binary_upload: false,
    skip_screenshots: true,
    skip_metadata: true,
    force: true
  })
end

desc "Deploy a new version to the App Store"
lane :release do |options|

  version = options[:version]
  raise "You must specify a version in A.B.X format to deploy." if version.nil? || version.scan(/\d+\.\d+\.\d+/).length == 0

  ensure_git_status_clean

  increment_version_number version_number: version
  increment_build_number

  # Generate release notes from CHANGELOG
  changelog_filename = '../CHANGELOG.yml'
  changelog_yaml = YAML.load_file(changelog_filename)
  release_notes = changelog_yaml['upcoming'].map{ |note| note.prepend '- ' }.join("\n")

  changelog_contents = File.read(changelog_filename)
  existing_releases = changelog_contents.split('releases:').last
  this_release = changelog_yaml['upcoming'].map{ |note| note.prepend '  ' }.join("\n")
  changelog_contents = <<-EOS
upcoming:

releases:
- version: #{version}
  date: #{Time.new.strftime("%Y-%m-%d")}
  notes:
#{this_release}
#{existing_releases}
EOS

  File.open(changelog_filename, 'w') { |file| file.puts changelog_contents }

  sync_code_signing

  build_ios_app

  upload_to_app_store({
    skip_binary_upload: false,
    skip_screenshots: true,
    skip_metadata: true,
    force: true
  })
  # frameit

  # Make sure our directory is clean, except for changes Fastlane has made
  #clean_build_artifacts

  # Tag release and push to GitHub
  sh "git add .. ; git commit -m 'Deploying version #{version}.'" # Can't use commit_version_bump to include changelog changes
  add_git_tag tag: version
  push_to_git_remote
end


desc "Capture Screenshots"
lane :screenshots do
  devices = ['iPhone 8 Plus', 'iPhone 11 Pro', 'iPhone 11 Pro Max', 'iPad Pro (12.9-inch) (3rd generation)']
  languages = ['en-US', 'de-DE']
  os_version = '13.3'
  
  Dir.mktmpdir do |tmp_dir|
    xcodebuild({
      workspace: "PhotoStickers.xcworkspace",
      scheme: "MessagesExtension",
      configuration: "Prefilled",
      derivedDataPath: tmp_dir,
      xcargs: "-sdk iphonesimulator -destination 'generic/platform=iOS Simulator' SYMROOT=#{tmp_dir}"
    })
    app_path = sh("find #{tmp_dir} -name *.app -type d").strip()
    

    languages.each do |lang|

      prepare_simulators(devices, os_version, app_path, lang)

      capture_screenshots({
        devices: devices,
        languages: [lang],
      })
    end
  end
end


desc "Prebuild for Simulator"
lane :simulator_build do
  devices = ['iPhone 11 Pro']
  lang = 'en-US'
  os_version = '13.3'

  Dir.mktmpdir do |tmp_dir|
    xcodebuild({
      workspace: "PhotoStickers.xcworkspace",
      scheme: "MessagesExtension",
      configuration: "Prefilled",
      derivedDataPath: tmp_dir,
      xcargs: "-sdk iphonesimulator -destination 'generic/platform=iOS Simulator' SYMROOT=#{tmp_dir}"
    })
    app_path = sh("find #{tmp_dir} -name *.app -type d").strip()
    prepare_simulators(devices, os_version, app_path, lang)
  end
end


desc "Upload metadata"
lane :upload_metadata do
  upload_to_app_store({
    skip_binary_upload: true,
    skip_screenshots: true,
    skip_metadata: false,
    force: true
  })
end


desc "Upload screenshots"
lane :upload_screenshots do
  upload_to_app_store({
    skip_binary_upload: true,
    skip_screenshots: false,
    skip_metadata: true,
    force: true
  })
end

desc "Updates the storyboard identifier Swift values."
lane :storyboard_ids do
  sh "cd .. ; bundle exec sbconstants ./Shared/Services/StoryboardIdentifiers.swift --source-dir ./ --swift"
end

desc "Reorganizes Xcode project folder to match Xcode groups."
lane :reorganize_project_folder do
  sh "cd .. ; bundle exec synx --exclusion Metadata --exclusion Deployment --exclusion Config --no-sort-by-name PhotoStickers.xcodeproj"
end

desc "Install dependencies (gems, cocoapods)"
lane :install_dependencies do
  bundle_install
  cocoapods({
    repo_update: true
  })
end

desc "Update dependencies (bundler, gems, cocoapods)"
lane :update_dependencies do
  sh "cd ..; gem install bundler"
  sh "cd ..; bundle update"
  sh "cd ..; bundle exec pod update"
end

desc "Delete cocoapods from the project and reinstall"
lane :reintegrate do
  sh "cd ..; bundle update"
  sh "cd ..; bundle exec pod deintegrate PhotoStickers.xcodeproj"
  #sh "bundle exec pod clean"
  cocoapods
end


error do |lane, exception|
  if lane == :release
    puts "Unable to release, resetting git repository."
    clean_build_artifacts
    reset_git_repo
  end
end


def prepare_simulators(devices, os_version, app_path, lang)
  UI.message("Installing App")
  available_sims = FastlaneCore::Simulator.all
  devices.each do |sim_name|
    sim = available_sims.detect { |d| sim_name == d.name && os_version == d.os_version }
    if sim.nil?
      UI.error("Device not found: #{sim_name}")
      `xcrun simctl list`
      next
    end
    sim_full_name = "#{sim.name} (#{sim.os_version})"

    reset_simulator(sim, lang)

    UI.message("Boot #{sim_full_name}")
    `xcrun simctl boot #{sim.udid} > /dev/null 2>&1`

    sleep 5
    
    UI.message("List of simulators")
    `xcrun simctl list`

    UI.message("Install App on #{sim_full_name}")
    `xcrun simctl install #{sim.udid} #{app_path}`

    sleep 5
  end
  
end

def reset_simulator(simulator, language)
  simulator.reset
  
  UI.message("Erasing #{simulator.name}")
  `xcrun simctl erase #{simulator.udid} &> /dev/null`
  
  locale = language.sub("-", "_")
  plist = {
    AppleLocale: locale,
    AppleLanguages: [language]
  }
  UI.message("Localizing #{simulator.name} (AppleLocale=#{locale} AppleLanguages=[#{language}])")
  plist_path = "#{ENV['HOME']}/Library/Developer/CoreSimulator/Devices/#{simulator.udid}/data/Library/Preferences/.GlobalPreferences.plist"
  File.write(plist_path, Plist::Emit.dump(plist))
end
